﻿using System.Collections;
using Basic.FormCollect;
using Basic.FormCollect.Model;
using Basic.FormModel.Column;
using Basic.FormModel.Group;
using Basic.FormRemoteModel;
using Basic.FormRemoteModel.Form.Model;
using Basic.FormService.Helper;
using Basic.FormService.Interface;
using WeDonekRpc.Helper;
namespace Basic.FormService.Extend
{
    internal class FormColSelectService : IFormColSelectService
    {
        private readonly ICustomTableCollect _Table;
        private readonly ITableGroupCollect _TableGroup;
        private readonly ITableColumnCollect _TableColumn;
        public FormColSelectService ( ICustomTableCollect table,
            ITableGroupCollect tableGroup,
            ITableColumnCollect tableColumn )
        {
            this._Table = table;
            this._TableGroup = tableGroup;
            this._TableColumn = tableColumn;
        }
        public class _TableDto
        {
            public long Id { get; set; }
            public string Title { get; set; }

            public FormTableType TableType { get; set; }
        }

        private StructureColumn _FormatCol ( TableColumnBase col )
        {
            StructureColumn column = new StructureColumn
            {
                Id = col.Id,
                Label = col.ColTitle,
                Name = col.ColName,
                Type = StructureType.Column,
                DataType = col.DataType,
                FuncType = col.FuncType,
                Sort = col.Sort
            };
            if ( col.FuncType == DataFuncType.选项值 || col.FuncType == DataFuncType.字典项 || col.FuncType == DataFuncType.树形字典 )
            {
                Dictionary<string, object> dic = col.ControlSet.Json<Dictionary<string, object>>();
                if ( col.FuncType == DataFuncType.选项值 )
                {
                    if ( dic.TryGetValue("items", out object obj) )
                    {
                        IList list = obj as IList;
                        KeyValuePair<string, string>[] items = new KeyValuePair<string, string>[list.Count];
                        int i = 0;
                        foreach ( IDictionary<string, object> t in list )
                        {
                            object k = t["value"];
                            items[i++] = new KeyValuePair<string, string>(k == null ? null : Convert.ToString(k), Convert.ToString(t["text"]));
                        }
                        column.Items = items;
                    }
                }
                else if ( dic.TryGetValue("dicId", out object val) && val != null )
                {
                    column.DicId = Convert.ToInt64(val);
                }
            }
            return column;
        }
        private StructureColumn[] _GetChindren ( _TableDto[] tables, TableColumnBase[] cols, TableGroupItem[] groups )
        {
            return tables.ConvertAll(a =>
            {
                StructureColumn[] child = null;
                if ( a.TableType == FormTableType.单一表单 || groups.IsNull() )
                {
                    child = cols.Where(c => c.TableId == a.Id).OrderBy(a => a.Sort).Select(this._FormatCol).ToArray();
                }
                else
                {
                    List<StructureColumn> colList = cols.Where(c => c.TableId == a.Id && c.GroupId == 0).Select(c => new StructureColumn
                    {
                        Id = c.Id,
                        Label = c.ColTitle,
                        Name = c.ColName,
                        Type = StructureType.Column,
                        DataType = c.DataType,
                        FuncType = c.FuncType,
                        Sort = c.Sort
                    }).ToList();
                    groups.ForEach(c =>
                    {
                        if ( c.ParentId == 0 )
                        {
                            StructureColumn[] t = this._GetChindren(c, cols, groups);
                            if ( !t.IsNull() )
                            {
                                colList.Add(new StructureColumn
                                {
                                    Id = c.Id,
                                    Label = c.GroupName,
                                    Type = StructureType.Group,
                                    Sort = c.Sort,
                                    Children = t
                                });
                            }
                        }
                    });
                    if ( colList.Count > 0 )
                    {
                        child = colList.OrderBy(a => a.Sort).ToArray();
                    }
                }
                StructureColumn col = new StructureColumn
                {
                    Id = a.Id,
                    Label = a.Title,
                    Type = a.TableType == FormTableType.多行列表 ? StructureType.Table : StructureType.Single,
                    Children = child
                };
                return col;
            });
        }
        private StructureColumn[] _GetChindren ( TableGroupItem group, TableColumnBase[] cols, TableGroupItem[] groups )
        {
            List<StructureColumn> colList = cols.Where(c => c.GroupId == group.Id).Select(c => new StructureColumn
            {
                Id = c.Id,
                Label = c.ColTitle,
                Name = c.ColName,
                Type = StructureType.Column,
                DataType = c.DataType,
                FuncType = c.FuncType,
                Sort = c.Sort
            }).ToList();
            groups.ForEach(c =>
            {
                if ( c.ParentId != group.Id )
                {
                    return;
                }
                StructureColumn[] t = this._GetChindren(group, cols, groups);
                if ( !t.IsNull() )
                {
                    colList.Add(new StructureColumn
                    {
                        Id = c.Id,
                        Label = c.GroupName,
                        Type = StructureType.Group,
                        Children = t,
                        Sort = c.Sort
                    });
                }
            });
            if ( colList.Count > 0 )
            {
                return colList.OrderBy(a => a.Sort).ToArray();
            }
            return null;
        }
        public StructureColumn[] Gets ( long formId, FormGetParam param )
        {
            TableColumnBase[] cols = this._TableColumn.GetsByFormId<TableColumnBase>(formId, new TableColGetParam
            {
                DataType = param.DataType.GetDataType(),
                ColType = param.FuncType.ToControlType()
            });
            if ( cols.IsNull() )
            {
                return Array.Empty<StructureColumn>();
            }
            if ( !param.TableId.IsNull() )
            {
                cols = cols.FindAll(c => param.TableId.Contains(c.TableId));
                if ( cols.IsNull() )
                {
                    return Array.Empty<StructureColumn>();
                }
            }
            _TableDto[] tables = this._Table.Gets<_TableDto>(cols.Distinct(c => c.TableId));
            if ( tables.IsNull() )
            {
                return Array.Empty<StructureColumn>();
            }
            TableGroupItem[] groups = null;
            long[] gIds = tables.Convert(c => c.TableType == FormTableType.多行列表, c => c.Id);
            if ( !gIds.IsNull() )
            {
                groups = this._TableGroup.GetsByTableId<TableGroupItem>(gIds);
            }
            return this._GetChindren(tables, cols, groups);
        }
    }
}
